package board;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Vector;

public class State{
	static char[][] positions;
	boolean whitesTurn;
	boolean gameOver=false;
	boolean gameIsTie=false;
	int turnNumber;
	float blackPieceValue;
	float whitePieceValue;
	
	char[][] savedPositions;
	boolean savedWhitesTurn;
	boolean savedGameOver;
	boolean savedGameIsTie;
	int savedTurnNumber;
	float savedBlackPieceValue;
	float savedWhitePieceValue;
	
	public State(){
		
	}
	
	/*public State(char[][] parmPositions,boolean parmWhitesTurn,boolean parmGameOver,int parmTurnNumber,float parmBlackPieceValue,float parmWhitePieceValue){
		positions=parmPositions;
		whitesTurn=parmWhitesTurn;
		gameOver=parmGameOver;
		turnNumber=parmTurnNumber;
		blackPieceValue=parmBlackPieceValue;
		whitePieceValue=parmWhitePieceValue;
	}
	
	public static State newinstance(State boardState) {
	    return new State(boardState.positions,boardState.whitesTurn,boardState.gameOver,boardState.turnNumber,boardState.blackPieceValue,boardState.whitePieceValue);
	  }*/
	
//	k=king,q=queen,b=bishop,n=knight,r=rook,p=pawn
//  black lowercase, white uppercase
	public void initializeBoard(){
		positions = new char[5][6];
		savedPositions = new char[5][6];//set this up now so we don't have to spend time creating the new object during saveState.
		whitesTurn=true;
		turnNumber=1;
		blackPieceValue=25;//piece value of all pieces except the king
		whitePieceValue=25;//piece value of all pieces except the king

		
		//starting state for normal game
		positions[0][0]='k';
		positions[1][0]='q';
		positions[2][0]='b';
		positions[3][0]='n';
		positions[4][0]='r';
		positions[0][1]='p';
		positions[1][1]='p';
		positions[2][1]='p';
		positions[3][1]='p';
		positions[4][1]='p';
		positions[0][2]='.';
		positions[1][2]='.';
		positions[2][2]='.';
		positions[3][2]='.';
		positions[4][2]='.';
		positions[0][3]='.';
		positions[1][3]='.';
		positions[2][3]='.';
		positions[3][3]='.';
		positions[4][3]='.';
		positions[0][4]='P';
		positions[1][4]='P';
		positions[2][4]='P';
		positions[3][4]='P';
		positions[4][4]='P';
		positions[0][5]='R';
		positions[1][5]='N';
		positions[2][5]='B';
		positions[3][5]='Q';
		positions[4][5]='K';
		
		/*4 W
		kqbnr
		ppp..
		...P.
		...p.
		PPP..
		RNBQK
		Board has value: 0.0*/
		/*
		  turnNumber=4;
		  positions[0][0]='k';
			positions[1][0]='q';
			positions[2][0]='b';
			positions[3][0]='n';
			positions[4][0]='r';
			positions[0][1]='p';
			positions[1][1]='p';
			positions[2][1]='p';
			positions[3][1]='.';
			positions[4][1]='.';
			positions[0][2]='.';
			positions[1][2]='.';
			positions[2][2]='.';
			positions[3][2]='P';
			positions[4][2]='.';
			positions[0][3]='.';
			positions[1][3]='.';
			positions[2][3]='.';
			positions[3][3]='p';
			positions[4][3]='.';
			positions[0][4]='P';
			positions[1][4]='P';
			positions[2][4]='P';
			positions[3][4]='.';
			positions[4][4]='.';
			positions[0][5]='R';
			positions[1][5]='N';
			positions[2][5]='B';
			positions[3][5]='Q';
			positions[4][5]='K';
			*/
		
		/*state produced in an actual alpha-beta game;
		turnNumber=4;
		positions[0][0]='k';
		positions[1][0]='q';
		positions[2][0]='b';
		positions[3][0]='n';
		positions[4][0]='r';
		positions[0][1]='p';
		positions[1][1]='p';
		positions[2][1]='p';
		positions[3][1]='.';
		positions[4][1]='.';
		positions[0][2]='.';
		positions[1][2]='.';
		positions[2][2]='.';
		positions[3][2]='p';
		positions[4][2]='.';
		positions[0][3]='.';
		positions[1][3]='.';
		positions[2][3]='.';
		positions[3][3]='.';
		positions[4][3]='.';
		positions[0][4]='P';
		positions[1][4]='P';
		positions[2][4]='P';
		positions[3][4]='P';
		positions[4][4]='.';
		positions[0][5]='R';
		positions[1][5]='N';
		positions[2][5]='B';
		positions[3][5]='Q';
		positions[4][5]='K';
		*/
		
		/*state with the white king beginning in danger
		kqbnr
		p.ppp
		.p...
		..K..
		PPPPP
		RNBQ.
		//should evaluate to a loss for white at depth 6.
		//the following is how it will look after 5.
		k.bnr
		pqp.p
		.p.p.
		....K
		PPPPP
		RNBQ.
		*/
		/*
		turnNumber=4;
		positions[0][0]='k';
		positions[1][0]='q';
		positions[2][0]='b';
		positions[3][0]='n';
		positions[4][0]='r';
		positions[0][1]='p';
		positions[1][1]='.';
		positions[2][1]='p';
		positions[3][1]='p';
		positions[4][1]='p';
		positions[0][2]='.';
		positions[1][2]='p';
		positions[2][2]='.';
		positions[3][2]='.';
		positions[4][2]='.';
		positions[0][3]='.';
		positions[1][3]='.';
		positions[2][3]='K';
		positions[3][3]='.';
		positions[4][3]='.';
		positions[0][4]='P';
		positions[1][4]='P';
		positions[2][4]='P';
		positions[3][4]='P';
		positions[4][4]='P';
		positions[0][5]='R';
		positions[1][5]='N';
		positions[2][5]='B';
		positions[3][5]='Q';
		positions[4][5]='.';*/
		
	}
	
	public void saveState(){
		savedWhitesTurn=whitesTurn;
		savedGameOver=gameOver;
		savedGameIsTie=gameIsTie;
		savedTurnNumber=turnNumber;
		savedBlackPieceValue=blackPieceValue;
		savedWhitePieceValue=whitePieceValue;
		for(int y=0;y<6;y++){
			for(int x=0;x<5;x++){
				savedPositions[x][y]=positions[x][y];
			}
		}
		
	}
	
	public void restoreState(){
		whitesTurn=savedWhitesTurn;
		gameOver=savedGameOver;
		gameIsTie=savedGameIsTie;
		turnNumber=savedTurnNumber;
		blackPieceValue=savedBlackPieceValue;
		whitePieceValue=savedWhitePieceValue;
		for(int y=0;y<6;y++){
			for(int x=0;x<5;x++){
				positions[x][y]=savedPositions[x][y];
			}
		}
	}

	public void drawBoard(PrintStream stream) {
		stream.print(turnNumber);
		if(whitesTurn) stream.print(" W\n");
		else stream.print(" B\n");
		for(int y=0;y<6;y++){
			for(int x=0;x<5;x++){
				stream.print(positions[x][y]);
			}
			stream.print('\n');
		}
		stream.print("Board has value: "+calcBoardValueNoMove()+"\n");
	}
	
	public void genmovesforpiece(int x, int y, Vector MoveList){
		if(whitesTurn){
			switch (positions[x][y]) {
			  case '.': break;
			  case 'p': break;
			  case 'k': break;
        	  case 'q': break;
        	  case 'b': break;
              case 'n': break;
              case 'r': break;
			  case 'P':  whitePawnMoves(x,y, MoveList);break;
			  case 'K':  whiteKingMoves(x,y,MoveList);break;
        	  case 'Q':  whiteQueenMoves(x,y,MoveList);break;
        	  case 'B':  whiteBishopMoves(x,y,MoveList);break;
        	  case 'N':  whiteKnightMoves(x,y, MoveList);break;
        	  case 'R':  whiteRookMoves(x,y,MoveList);break;
			  default: System.out.println("Invalid piece.");break;
			}
		}else{//blacks turn
			switch (positions[x][y]) {
			  case '.':  break;
			  case 'P':  break;
			  case 'K':  break;
        	  case 'Q':  break;
        	  case 'B':  break;
        	  case 'N':  break;
        	  case 'R':  break;
			  case 'p':  blackPawnMoves(x,y,MoveList); break;
			  case 'k':  blackKingMoves(x,y,MoveList);break;
          	  case 'q':  blackQueenMoves(x,y,MoveList);break;
          	  case 'b':  blackBishopMoves(x,y,MoveList);break;
              case 'n':  blackKnightMoves(x,y,MoveList);break;
              case 'r':  blackRookMoves(x,y,MoveList);break;
			  default: System.out.println("Invalid piece.");break;
		   }
		}
	}
	
	public void whiteKingMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//8 possible moves for the king.
		
		//down and to the right
		newx=x+1;
		newy=y+1;
		if(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//right
		newx=x+1;
		newy=y;
		if(newx<=4){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//up and right
		newx=x+1;
		newy=y-1;
		if(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//up
		newx=x;
		newy=y-1;
		if(newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//up and left
		newx=x-1;
		newy=y-1;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//left
		newx=x-1;
		newy=y;
		if(newx>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//down and left
		newx=x-1;
		newy=y-1;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//down
		newx=x;
		newy=y+1;
		if(newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
	}

	private void addMove(int x, int y, Vector MoveList, int newx, int newy) {
		Move newMove = new Move();
		newMove.fromSquare.SetSquare(x,y);
		newMove.toSquare.SetSquare(newx, newy);
		newMove.pieceMoved=pieceAt(x,y);
		newMove.pieceCaptured=pieceAt(newx,newy);
		MoveList.addElement(newMove);
	}
	
	public void blackKingMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//8 possible moves for the king.
		
		//down and to the right
		newx=x+1;
		newy=y+1;
		if(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//right
		newx=x+1;
		newy=y;
		if(newx<=4){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up and right
		newx=x+1;
		newy=y-1;
		if(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up
		newx=x;
		newy=y-1;
		if(newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up and left
		newx=x-1;
		newy=y-1;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//left
		newx=x-1;
		newy=y;
		if(newx>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down and left
		newx=x-1;
		newy=y-1;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down
		newx=x;
		newy=y+1;
		if(newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
	}
	
	public void whiteKnightMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//8 possible moves for the knight.
		
		//up one right two
		newx=x+2;
		newy=y-1;
		if(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up one left two
		newx=x-2;
		newy=y-1;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down one right two
		newx=x+2;
		newy=y+1;
		if(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down one left two
		newx=x-2;
		newy=y+1;
		if(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up two right one
		newx=x+1;
		newy=y-2;
		if(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up two left one
		newx=x-1;
		newy=y-2;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down two right one
		newx=x+1;
		newy=y+2;
		if(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down two left one
		newx=x-1;
		newy=y+2;
		if(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(blackPieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		
	}
	
	public void blackKnightMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//up one right two
		newx=x+2;
		newy=y-1;
		if(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up one left two
		newx=x-2;
		newy=y-1;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down one right two
		newx=x+2;
		newy=y+1;
		if(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//down one left two
		newx=x-2;
		newy=y+1;
		if(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up two right one
		newx=x+1;
		newy=y-2;
		if(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x,y,MoveList,newx,newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x,y,MoveList,newx,newy);
			}
		}
		//up two left one
		newx=x-1;
		newy=y-2;
		if(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//down two right one
		newx=x+1;
		newy=y+2;
		if(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
		//down two left one
		newx=x-1;
		newy=y+2;
		if(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
			}
		}
	}
	
	public void whiteQueenMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//up and to the right
		newx=x+1;
		newy=y-1;
	    while(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//up and to the left
		newx=x-1;
		newy=y-1;
		while(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//down and to the right
		newx=x+1;
		newy=y+1;
		while(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//down and to the left
		newx=x-1;
		newy=y+1;
		while(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//move right
		newx=x+1;
		while(newx<=4){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				newx++;
				continue;
			}
			if(blackPieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(whitePieceAt(newx,y)){
				break;
			}
		}
		//move left
		newx=x-1;
		while(newx>=0){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				newx--;
				continue;
			}
			if(blackPieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(whitePieceAt(newx,y)){
				break;
			}			
		}
		newy=y+1;
		while(newy<=5){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				newy++;
				continue;
			}
			if(blackPieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(whitePieceAt(x,newy)){
				break;
			}	
		}
		newy=y-1;
		while(newy>=0){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				newy--;
				continue;
			}
			if(blackPieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(whitePieceAt(x,newy)){
				break;
			}	
		}
	}
	
	public void blackQueenMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//up and to the right
		newx=x+1;
		newy=y-1;
	    while(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//up and to the left
		newx=x-1;
		newy=y-1;
		while(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//down and to the right
		newx=x+1;
		newy=y+1;
		while(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//down and to the left
		newx=x-1;
		newy=y+1;
		while(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//move right
		newx=x+1;
		while(newx<=4){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				newx++;
				continue;
			}
			if(whitePieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(blackPieceAt(newx,y)){
				break;
			}
		}
		//move left
		newx=x-1;
		while(newx>=0){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				newx--;
				continue;
			}
			if(whitePieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(blackPieceAt(newx,y)){
				break;
			}			
		}
		//move down
		newy=y+1;
		while(newy<=5){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				newy++;
				continue;
			}
			if(whitePieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(blackPieceAt(x,newy)){
				break;
			}	
		}
		//move up
		newy=y-1;
		while(newy>=0){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				newy--;
				continue;
			}
			if(whitePieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(blackPieceAt(x,newy)){
				break;
			}	
		}
	}
	
	public void whiteBishopMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//up and to the right
		newx=x+1;
		newy=y-1;
	    while(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//up and to the left
		newx=x-1;
		newy=y-1;
		while(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//down and to the right
		newx=x+1;
		newy=y+1;
		while(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
		//down and to the left
		newx=x-1;
		newy=y+1;
		while(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				continue;
			}
			if(blackPieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				break;
			}
			if(whitePieceAt(newx,newy)){
				break;
			}
		}
	}
	
	public void blackBishopMoves(int x, int y, Vector MoveList){
		int newx, newy;
		//up and to the right
		newx=x+1;
		newy=y-1;
	    while(newx<=4&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy--;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//up and to the left
		newx=x-1;
		newy=y-1;
		while(newx>=0&&newy>=0){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy--;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//down and to the right
		newx=x+1;
		newy=y+1;
		while(newx<=4&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx++;
				newy++;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
		//down and to the left
		newx=x-1;
		newy=y+1;
		while(newx>=0&&newy<=5){
			if(pieceAt(newx,newy)=='.'){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				continue;
			}
			if(whitePieceAt(newx,newy)){
				addMove(x, y, MoveList, newx, newy);
				newx--;
				newy++;
				break;
			}
			if(blackPieceAt(newx,newy)){
				break;
			}
		}
	}
	
	public void whiteRookMoves(int x, int y, Vector MoveList){
		//move right
		for(int newx=x+1;newx<=4;++newx){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				continue;
			}
			if(blackPieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(whitePieceAt(newx,y)){
				break;
			}
		}
		//move left
		for(int newx=x-1;newx>=0;--newx){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				continue;
			}
			if(blackPieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(whitePieceAt(newx,y)){
				break;
			}			
		}
		//move down
		for(int newy=y+1;newy<=5;++newy){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				continue;
			}
			if(blackPieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(whitePieceAt(x,newy)){
				break;
			}	
		}
		//move up
		for(int newy=y-1;newy>=0;--newy){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				continue;
			}
			if(blackPieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(whitePieceAt(x,newy)){
				break;
			}	
		}
	}
	
	public void blackRookMoves(int x, int y, Vector MoveList){
		//move right
		for(int newx=x+1;newx<=4;++newx){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				continue;
			}
			if(whitePieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(blackPieceAt(newx,y)){
				break;
			}
		}
		//move left
		for(int newx=x-1;newx>=0;--newx){
			if(pieceAt(newx,y)=='.'){
				addMove(x, y, MoveList, newx, y);
				continue;
			}
			if(whitePieceAt(newx,y)){
				addMove(x, y, MoveList, newx, y);
				break;
			}
			if(blackPieceAt(newx,y)){
				break;
			}			
		}
		//move down
		for(int newy=y+1;newy<=5;++newy){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				continue;
			}
			if(whitePieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(blackPieceAt(x,newy)){
				break;
			}	
		}
		//move up
		for(int newy=y-1;newy>=0;--newy){
			if(pieceAt(x,newy)=='.'){
				addMove(x, y, MoveList, x, newy);
				continue;
			}
			if(whitePieceAt(x,newy)){
				addMove(x, y, MoveList, x, newy);
				break;
			}
			if(blackPieceAt(x,newy)){
				break;
			}	
		}
	}
	
	public void whitePawnMoves(int x, int y, Vector MoveList){
		if(pieceAt(x,y-1)=='.'){
		//pawn will never be in the top row
		//pawn would have converted to queen,
		//no need for checking if y-1 < 0
			addMove(x, y, MoveList, x, y-1);
		}
		if(x-1>=0){
			if(blackPieceAt(x-1,y-1)){
				addMove(x, y, MoveList, x-1, y-1);
			}
		}
		if(x+1<=4){
			if(blackPieceAt(x+1,y-1)){
				addMove(x, y, MoveList, x+1, y-1);
			}
		}
	}
	
	public void blackPawnMoves(int x, int y, Vector MoveList){
		if(pieceAt(x,y+1)=='.'){
		//pawn will never be in the bottom row
		//pawn would have converted to queen,
		//no need for checking if y+1 >5 0
			addMove(x, y, MoveList, x, y+1);
		}
		if(x-1>=0){
			if(whitePieceAt(x-1,y+1)){
				addMove(x, y, MoveList, x-1, y+1);
			}
		}
		if(x+1<=4){
			if(whitePieceAt(x+1,y+1)){
				addMove(x, y, MoveList, x+1, y+1);
			}
		}
	}
	
	public Vector moveGen(){
		Vector MoveList;
		MoveList = new Vector(16,8);
		for(int x=0;x<5;x++){
			for(int y=0;y<6;y++){
				genmovesforpiece(x,y,MoveList);
			}
		}
		for(int i=0;i<MoveList.size();i++){
			((Move)MoveList.elementAt(i)).Value=calcBoardValue((Move)MoveList.elementAt(i));
		}
		return MoveList;
	}
	
	public boolean winningMove(Move aMove){
		if((aMove.pieceCaptured=='k')||(aMove.pieceCaptured=='K')){
			return true;
		}
		else return false;
	}
	
	//this is an expensive check because it generates an entire moveList for the next move!
	//need to find a better way.
	public boolean tieMove(Move aMove){
		Vector moveList;
		char pieceMoved=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
		char pieceCaptured=positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()];
		  makeMove(aMove);
		  moveList=moveGen();
		  undoMove(aMove);
		  if(moveList.size()<1){
			  //"No legal moves. Game is a draw."
			  return true;
		  }
		  else return false;
	}
	
	
	public void undoMove(Move aMove){
		//switch the turn and roll back the turn number if necessary.
		if(whitesTurn){
			turnNumber--;
		}
		whitesTurn=!whitesTurn;
		gameOver=false;
		gameIsTie=false;
		
		positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=aMove.pieceCaptured;
		positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()]=aMove.pieceMoved;
		
	}
	
	//currently checks to make sure player is moving own piece and not capturing own piece.
	//Does not check to make sure move was legal such as pawn moved forward or did a diagonal capture.
	public boolean makeMoveRulesEnforced(Move aMove){
		Vector moveList;//used after a move is made to store a list of all possible next moves and check if the game is a draw
		aMove.pieceMoved=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
		aMove.pieceCaptured=positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()];
		
		//blacks turn
		if(whitesTurn==false){
			//check if we are moving a legal piece.
			if(!blackPieceAt(aMove.fromSquare.GetX(),aMove.fromSquare.GetY())){
				System.out.println("Black player trying to move an empty square or white piece.");
				return false;
			}
			//check if we are capturing a legal piece.
			if(blackPieceAt(aMove.toSquare.GetX(),aMove.toSquare.GetY())){
				System.out.println("Black player trying to capture own piece.");
				return false;
			}
			switch(aMove.pieceMoved){
				case 'p':
					if(aMove.pieceCaptured=='.'){
					  if (aMove.fromSquare.GetX()!=aMove.toSquare.GetX()){
						  System.out.println("Illegal pawn move.");
						  return false;
					  }
					}
					if (aMove.fromSquare.GetY()-aMove.toSquare.GetY()!=-1){
						System.out.println("Illegal pawn move.");
						return false;
					}
				case 'q':
					if(
						(aMove.fromSquare.GetX()!=aMove.toSquare.GetX())&&(aMove.fromSquare.GetY()!=aMove.toSquare.GetY())
					){
						if(
								Math.abs(
									(aMove.fromSquare.GetY())-(aMove.toSquare.GetY()))
								!=
								Math.abs(
									(aMove.fromSquare.GetX())-(aMove.toSquare.GetX()))
						  ){
							System.out.println("Illegal queen move.");
							return false;
						}
					}
					
			}
//			check if this is a winning move
			if (winningMove(aMove)){
				gameOver=true;
			}
			//move the piece
			positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
			//check for black queen promotion
			if((positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=='p')&&(aMove.toSquare.GetY()==5)){
				positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]='q';
			}
			turnNumber++;
			whitesTurn=true;
		}
		else{//it's whites turn
			//check if we are moving a legal piece.
			if(!whitePieceAt(aMove.fromSquare.GetX(),aMove.fromSquare.GetY())){
				System.out.println("White player trying to move an empty square or black piece.");
				return false;
			}
//			check if we are capturing a legal piece.
			if(whitePieceAt(aMove.toSquare.GetX(),aMove.toSquare.GetY())){
				System.out.println("White player trying to capture own piece.");
				return false;
			}
			//check if this is a winning move
			if (winningMove(aMove)){
				gameOver=true;
			}
			//move the piece
			positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
			//check for white queen promotion
			if((positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=='P')&&(aMove.toSquare.GetY()==0)){
				positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]='Q';
			}
			whitesTurn=false;
		}
		//in all cases the square the piece was moved from becomes blank.
		positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()]='.';
		
		/*May 27 This code is unneccesarry
		 * 
		 //this test for tie games is expensive!! is there a better way???
		moveList=moveGen();
		if(moveList.size()<1){
			gameOver=true;
			gameIsTie=true;
		}
		*/
		return true;
	}
	
	public void makeMove(Move aMove){
		Vector moveList;//used after a move is made to store a list of all possible next moves and check if the game is a draw
		aMove.pieceMoved=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
		aMove.pieceCaptured=positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()];
		
		//check if this is a winning move
		if (winningMove(aMove)){
			gameOver=true;
		}
		
		if(whitesTurn==false){
//			move the piece
			positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
//			check for black queen promotion
			if((positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=='p')&&(aMove.toSquare.GetY()==5)){
				positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]='q';
			}
			turnNumber++;
			whitesTurn=true;
		}
		else{
//			move the piece
			positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()];
//			check for white queen promotion
			if((positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=='P')&&(aMove.toSquare.GetY()==0)){
				positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]='Q';
			}
			whitesTurn=false;
		}
		//in all cases the square the piece was moved from becomes blank.
		positions[aMove.fromSquare.GetX()][aMove.fromSquare.GetY()]='.';
		
		/*Can't actually tie to no legal remaining moves in minichess?a2-a3
		 * //this test for tie games is expensive!! is there a better way???
		moveList=moveGen();
		if(moveList.size()<1){
			gameOver=true;
			gameIsTie=true;
		}*/
		
	}
	
	public float calcBoardValue(Move aMove){
//		check if this is a winning move
		if(whitesTurn&&(positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=='k')){
			return 1;
		}
		else if(!whitesTurn&&(positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]=='K')){
			return 1;
		}
//		calculate the board value if aMove is taken.
		//give each side 1 point for its Pawn, 3 for its Bishop or Knight, 5 for its Rook, and 9 for its Queen.
		//Take the difference between the two sides, and divide it by 26 to normalize it.
		//This is the basic implementation as suggested by Bart Massey for HW2
		whitePieceValue=0;
		blackPieceValue=0;
		for(int x=0;x<5;x++){
			for(int y=0;y<6;y++){
				switch (positions[x][y]) {
				  case '.': break;
				  case 'p': blackPieceValue+=1;break;
				  case 'k': break;
	        	  case 'q': blackPieceValue+=9;break;
	        	  case 'b': blackPieceValue+=2.5;break;
	              case 'n': blackPieceValue+=3;break;
	              case 'r': blackPieceValue+=5;break;
				  case 'K': break;
				  case 'P': whitePieceValue+=1;break;
	        	  case 'Q': whitePieceValue+=9;break;
	        	  case 'B': whitePieceValue+=2.5;break;
	        	  case 'N': whitePieceValue+=3;break;
	        	  case 'R': whitePieceValue+=5;break;
				  default: System.out.println("Invalid piece.");break;
				}
			}
		}
		switch(positions[aMove.toSquare.GetX()][aMove.toSquare.GetY()]){
		  case '.': break;
		  case 'k': break;
		  case 'p': blackPieceValue-=1;break;
		  case 'q': blackPieceValue-=9;break;
		  case 'b': blackPieceValue-=3;break;
		  case 'n': blackPieceValue-=3;break;
		  case 'r': blackPieceValue-=5;break;
		  case 'K': break;
		  case 'P': whitePieceValue-=1;break;
		  case 'Q': whitePieceValue-=9;break;
		  case 'B': whitePieceValue-=3;break;
		  case 'N': whitePieceValue-=3;break;
		  case 'R': whitePieceValue-=5;break;
		  default: System.out.println("Invalid piece.");break;
		}
		if(whitesTurn) {
			/*if((savedTurnNumber<3)){
				if(positions[1][5]!='N'){
					return -1;
				}
				if(positions[3][5]!='Q'){
					return -1;
				}
				if(positions[4][5]!='K'){
					return -1;
				}
			}*/
			float value;
			value=(whitePieceValue-blackPieceValue)/26;
			if(value>=1){value=(float)0.9999;}//if there are multiple queens for one side the normalized value can be outside the range -1 to 1
			if(value<=-1){value=(float)-0.9999;}
			return value;
		}
		else {
			float value;
			value=(blackPieceValue-whitePieceValue)/26;
			if(value>=1){value=(float)0.99;}//if there are multiple queens for one side the normalized value can be outside the range -1 to 1
			if(value<=-1){value=(float)-0.99;}
			return (blackPieceValue-whitePieceValue)/26;
		}
	}
	
	public float calcBoardValueNoMove(){
		boolean whiteKingFound=false;
		boolean blackKingFound=false;
		whitePieceValue=0;
		blackPieceValue=0;
		for(int x=0;x<5;x++){
			for(int y=0;y<6;y++){
				switch (positions[x][y]) {
				  case '.': break;
				  case 'p': blackPieceValue+=1;break;
				  case 'k': blackKingFound=true;break;
	        	  case 'q': blackPieceValue+=9;break;
	        	  case 'b': blackPieceValue+=2.5;break;
	              case 'n': blackPieceValue+=3;break;
	              case 'r': blackPieceValue+=5;break;
				  case 'K': whiteKingFound=true;break;
				  case 'P': whitePieceValue+=1;break;
	        	  case 'Q': whitePieceValue+=9;break;
	        	  case 'B': whitePieceValue+=2.5;break;
	        	  case 'N': whitePieceValue+=3;break;
	        	  case 'R': whitePieceValue+=5;break;
				  default: System.out.println("Invalid piece.");break;
				}
			}
		}
		
		if(whitesTurn) {
			/*if((savedTurnNumber<3)){
				if(positions[1][5]!='N'){
					return -1;
				}
				if(positions[3][5]!='Q'){
					return -1;
				}
			}*/
			float value;
			if(!whiteKingFound) return -1;
			value=(whitePieceValue-blackPieceValue)/26;
			if(value>=1){value=(float)0.99;}
			if(value<=-1){value=(float)-0.99;}
			return value;
		}
		else {
			float value;
			if(!blackKingFound) return -1;
			value=(blackPieceValue-whitePieceValue)/26;
			if(value>=1){value=(float)0.99;}
			if(value<=-1){value=(float)-0.99;}
			return (blackPieceValue-whitePieceValue)/26;
		}
	}
	
	public char pieceAt(int x, int y){
		return positions[x][y];
	}
	
	public boolean blackPieceAt(int x, int y){
		switch (positions[x][y]){
		  case 'p': 
		  case 'k': 
      	  case 'q': 
      	  case 'b': 
          case 'n': 
          case 'r':  return true;
          default :  return false;
		}
	}
	public boolean whitePieceAt(int x, int y){
		switch (positions[x][y]){
		  case 'P': 
		  case 'K': 
      	  case 'Q': 
      	  case 'B': 
          case 'N': 
          case 'R':  return true;
          default :  return false;
		}
	}
	
	//when calling square the resulting square is only valid
	//if the boolean is true when return occurs
	public boolean findPiece(char piece,Square result){
		for(int x=0;x<5;x++){
			for(int y=0;y<6;y++){
				if (positions[x][y]==piece){
					result.SetSquare(x,y);
					return true;
				}
			}
		}
		return false;//we didn't find the piece. result is still set to false.
	}
	
	//5/13/2007 this reader is not correct.
	public static void readBoard(InputStream stream){
		try{
		  InputStreamReader streamReader=new InputStreamReader(stream);
		  for(int y=0;y<6;y++){
			for(int x=0;x<5;x++){
			  positions[x][y]=(char)streamReader.read();
			}
		  }
		}
		catch(Exception err){
		    err.printStackTrace();
		}
	}

}
